#!/usr/bin/env python3
"""
模拟站点数据生成器
基于现有数据的统计特征和日周期模式生成2025/8/27至2025/8/28的模拟数据
"""

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import os

def generate_simulated_station_data(existing_csv_path, output_csv_path=None, num_days=2):
    """
    基于现有数据生成模拟站点数据
    
    Args:
        existing_csv_path: 现有站点数据CSV文件路径
        output_csv_path: 输出文件路径，如果为None则覆盖原文件
        num_days: 需要生成的天数
    
    Returns:
        pandas.DataFrame: 包含原始数据和模拟数据的完整DataFrame
    """
    # 读取现有数据
    df = pd.read_csv(existing_csv_path)
    df['timestamp'] = pd.to_datetime(df['timestamp'], utc=True)
    
    # 分析最后2天的统计特征和日周期模式
    last_2_days = df[df['timestamp'] >= df['timestamp'].max() - timedelta(days=2)].copy()
    
    # 分析日周期模式
    def analyze_daily_patterns(data):
        patterns = {}
        data_copy = data.copy()
        data_copy['hour'] = data_copy['timestamp'].dt.hour + data_copy['timestamp'].dt.minute / 60
        
        for col in ['direct_irradiance', 'diffuse_irradiance', 'wind_speed', 'wind_direction', 'temperature']:
            hourly_stats = data_copy.groupby('hour')[col].agg(['mean', 'std']).reset_index()
            patterns[col] = hourly_stats
        return patterns
    
    patterns = analyze_daily_patterns(last_2_days)
    
    # 生成模拟数据
    simulated_data = []
    last_timestamp = df['timestamp'].max()
    
    for day in range(1, num_days + 1):
        current_date = last_timestamp + timedelta(days=day)
        
        # 生成一天的数据（96个时间点，15分钟间隔）
        for hour in range(24):
            for minute in [0, 15, 30, 45]:
                timestamp = current_date.replace(hour=hour, minute=minute, second=0, microsecond=0)
                hour_decimal = hour + minute / 60
                
                # 为每个变量生成基于日周期的模拟值
                row_data = {'timestamp': timestamp}
                
                for col in ['direct_irradiance', 'diffuse_irradiance', 'wind_speed', 'wind_direction', 'temperature']:
                    # 找到最接近的小时模式
                    pattern = patterns[col]
                    closest_hour_idx = (pattern['hour'] - hour_decimal).abs().idxmin()
                    
                    mean_val = pattern.loc[closest_hour_idx, 'mean']
                    std_val = max(pattern.loc[closest_hour_idx, 'std'], 0.1)  # 避免标准差为0
                    
                    # 生成随机值，保持合理的范围约束
                    if col == 'direct_irradiance':
                        value = max(0, np.random.normal(mean_val, std_val * 0.3))
                    elif col == 'diffuse_irradiance':
                        value = max(0, np.random.normal(mean_val, std_val * 0.3))
                    elif col == 'wind_speed':
                        value = max(0, np.random.normal(mean_val, std_val * 0.2))
                    elif col == 'wind_direction':
                        value = np.random.normal(mean_val, std_val * 0.2) % 360  # 保持在0-360度范围内
                    elif col == 'temperature':
                        value = np.random.normal(mean_val, std_val * 0.1)
                    
                    row_data[col] = round(value, 2)
                
                simulated_data.append(row_data)
    
    # 创建模拟数据DataFrame
    simulated_df = pd.DataFrame(simulated_data)
    
    # 合并原始数据和模拟数据
    combined_df = pd.concat([df, simulated_df], ignore_index=True)
    
    # 保存数据
    if output_csv_path is None:
        output_csv_path = existing_csv_path
    
    # 保存时去掉时区信息以保持格式一致
    combined_df['timestamp'] = combined_df['timestamp'].dt.strftime('%Y/%m/%d %H:%M')
    combined_df.to_csv(output_csv_path, index=False)
    
    print(f"成功生成 {num_days} 天模拟数据")
    print(f"原始数据点数: {len(df)}")
    print(f"模拟数据点数: {len(simulated_df)}")
    print(f"总数据点数: {len(combined_df)}")
    print(f"数据已保存到: {output_csv_path}")
    
    return combined_df

def validate_simulated_data(original_csv_path, simulated_csv_path):
    """
    验证模拟数据的合理性
    """
    original_df = pd.read_csv(original_csv_path)
    simulated_df = pd.read_csv(simulated_csv_path)
    
    original_df['timestamp'] = pd.to_datetime(original_df['timestamp'], utc=True)
    simulated_df['timestamp'] = pd.to_datetime(simulated_df['timestamp'], utc=True)
    
    print("数据验证结果:")
    print(f"原始数据时间范围: {original_df['timestamp'].min()} 到 {original_df['timestamp'].max()}")
    print(f"模拟后时间范围: {simulated_df['timestamp'].min()} 到 {simulated_df['timestamp'].max()}")
    print(f"总天数: {(simulated_df['timestamp'].max() - simulated_df['timestamp'].min()).days + 1}天")
    
    # 检查统计特性
    original_stats = original_df.describe()
    simulated_stats = simulated_df.describe()
    
    print("\n统计特性对比:")
    for col in ['direct_irradiance', 'diffuse_irradiance', 'wind_speed', 'wind_direction', 'temperature']:
        print(f"\n{col}:")
        print(f"  原始均值: {original_stats[col]['mean']:.2f}, 模拟均值: {simulated_stats[col]['mean']:.2f}")
        print(f"  原始标准差: {original_stats[col]['std']:.2f}, 模拟标准差: {simulated_stats[col]['std']:.2f}")

if __name__ == "__main__":
    # 生成模拟数据并覆盖原文件
    original_path = "station_data.csv"
    generate_simulated_station_data(original_path, num_days=2)
    
    # 验证生成的数据
    validate_simulated_data(original_path, original_path)
